home *** CD-ROM | disk | FTP | other *** search
- title DSHERC.ASM
- name DSHERC
- include DOS.MAC
- ;
- ; Assembler routines for the Hercules display driver. Mostly
- ; Graphics-mode, but a little text-mode stuff. In graphics mode,
- ; we deal strictly in "natural" screen coordinates, i.e., with
- ; the origin at the upper left corner.
-
- ; Addition of an optional status line at the top of the screen is
- ; handled rather uncleanly by just knowing that certain fields start
- ; 14 pixels lower than otherwise. To this routine, the "graphics
- ; area" is the rectangle swept by the crosshairs and cleared by
- ; dsclr; it is graphx by graphy pixels.
-
- ; Note that the byte-oriented references in adsmark, adsclr, adschar,
- ; and hcscroll is done purposely to accomodate an unfortunate design
- ; choice in the way the Eagle Computer addresses video ram.
-
- ; Modified 2/10/84: byte-oriented code for Eagle and saving and
- ; restoring es.
-
- ; Final 1.50 update 6/20/84
-
- ;;;;;;; public finddot
- public adsvec,adsxvec,adsmark,adsclr,adswipe
- public adsdot
- public adschar,dsrvid
- public hcscroll
-
-
- graphseg equ 0B800h ;Graphics buffer (page 1)
- textseg equ 0B000h ;Text buffer (page 0)
- XSIZE equ 720 ;Nr of vertical columns.
- YSIZE equ 348 ;Nr of horizontal lines.
- below_cline equ 270+4000h ;First pixel below status line.
-
-
- dseg dsherca ;Display driver data
-
- extrn color:word ;Color to draw anything.
- extrn hilight:word ;Highlight selected entities flag
- extrn graphx:word ;Graphics area width
- extrn graphy:word ; and height.
- extrn cline:word ;Status line flag.
-
-
- ninety dw 90 ;Number of bytes per row.
- hibits db 00000000b ;Bits 14 & 13 of vram address.
- db 00100000b
- db 01000000b
- db 01100000b
- xmask db 0 ;Clear-pixel mask for dsvec.
-
- chartab equ this byte ;Font definition table (see adschar)
- include hcfont.ai ;In a separate module.
-
-
- endds dsherca
- ;
- ;
- pseg dsherca_
-
-
- ; Internal routine to convert screen coordinates to graphics buffer
- ; address. Takes x-coordinate at ARGS, y-coordinate at ARGS+2,
- ; returns byte address in bx, bit number in cl (0=left).
-
- ; Incidentally returns byte address of dot at (0,y) in ax.
-
- ; Clobbers dx.
-
- hcdot proc near
- mov ax,args+2 ;Row number.
- mov bx,ax ;a copy.
- shr ax,1 ;Divide by
- shr ax,1 ; 4 and multiply
- mul ninety ; by 90.
- and bx,11b ;Low 2 bits of row number.
- or ah,hibits[bx] ;Move to bits 14 and 13.
- mov bx,args ;column number.
- mov cl,bl ;Copy it.
- shr bx,1 ;Divide by 8.
- shr bx,1
- shr bx,1
- and cl,111b ;Bit number.
- add bx,ax ;Byte address.
- ret
- hcdot endp
-
- ; Return dot location to a c program.
-
- ; finddot(x, y, &byte, &dot)
-
- ifdef NEEDED ;So far, it isn't.
- finddot proc far
- push bp
- mov bp,sp
- call hcdot ;Do the computation.
- xor ch,ch ;Zero-extend cl.
- mov si,args+4 ;Store
- mov [si],bx ; byte number,
- mov si,args+6 ; dot number.
- mov [si],cx
- pop bp
- ret
- finddot endp
- endif
-
-
-
- ; Complement the dot at screen coordinates (x,y)
- ;
- ; adsdot(x,y)
- ;
- adsdot proc far
- push bp ;Get a stack frame.
- mov bp,sp
- push es ; always save seg regs
- call hcdot ;Locate the dot in vram.
- mov ax,graphseg ;Base
- mov es,ax ; graphics RAM segment.
- mov al,10000000b ;xor mask.
- ror al,cl ;Position it over pixel.
- xor es:[bx],al ;Flip the pixel.
- pop es ; restore ES
- pop bp ;And stack frame.
- ret
- adsdot endp
- ;
- ;
- ; call adsvec(x1, y1, x2, y2)
- ;
- ; to draw a vector from (x1,y1) to (x2,y2) in current color.
- ;
- ; call adsxvec(x1, y1, x2, y2)
- ;
- ; to complement dots of vector from (x1,y1) to (x2,y2).
- ;
- rangex equ word ptr -2[bp] ;abs(x2-x1)
- rangey equ word ptr -4[bp] ;abs(y2-y1)
- yincalt equ word ptr -6[bp] ;address addend for y incrementation.
- patmask equ byte ptr -8[bp] ;line font pattern mask
- tempsiz equ 8
- ;
- adsvec proc far
- mov al,01111111b ;Clear-pixel mask.
- jmp veccmn ;Join adsxvec.
-
- adsxvec label far
- mov al,11111111b ;Don't clear pixel.
-
- veccmn:
- mov xmask,al ;Save mask (and flag).
- push bp
- mov bp,sp ;Make ourselves a stack frame.
- sub sp,tempsiz ;Reserve local variables.
- mov si,args+6 ;y2
- mov cx,args+2 ;y1
- sub si,cx ;y2-y1
- mov dx,args+4 ;x2
- mov bx,args ;x1
- sub dx,bx ;x2-x1
- mov rangex,dx
- mov rangey,si
- mov patmask,11111111b ;set solid line pattern
-
- ; To simplify the incrementation of x in the drawing loop, we start
- ; from the point with smaller x-coordinate.
- push bp ;Save for temp stack frame change.
- jge noswap
- neg rangex
- neg rangey
- add bp,4 ;Starting point is P2, not P1.
- noswap:
- call hcdot ;Get starting address in bx and cl.
- pop bp ;Make sure stack frame is right.
-
- ; Moving up or down one row is accomplished by adding plus or minus
- ; 2000h to the current byte address, and when that overflows (every
- ; 4 lines), adding plus or minus (90-8000h).
-
- mov si,2000H ;Row-increment addend.
- mov di,90-8000H ;Every-fourth-time correction.
- test byte ptr rangey+1,80h ;If y difference is
- jz posy
- neg rangey ; negative, invert it,
- neg si ; invert the y addends
- neg di ; also.
- posy: mov yincalt,di ;Save second y addend.
-
- ; al will be used to mask the bit for one dot out a byte,
- ; then ah will be xor'ed with it.
-
- mov al,xmask ;the mask (and dsvec/dsxvec flag).
- cmp al,11111111b ;If dsxvec,
- je xorit ; don't check color.
- xor ah,ah ;Bit=1 unless color==0.
- cmp ah,byte ptr color
- je dplus2
-
- cmp ah,byte ptr hilight ;Highlight vector ?
- je xorit ; no. skip pattern setup
- mov patmask,10101010b ; set highlight pattern
- push ax
- mov ax,rangex
- cmp ax,rangey ; Select pattern by movement direction
- pop ax
- jl xorit
- mov patmask,11001100b ; set highlight pattern
-
- xorit:
- mov ah,10000000B
- dplus2:
- ror ah,cl ;Position to starting pixel.
- ror al,cl
- ror patmask,cl ;Shift pattern mask to start pos
- ;
- ;
- push ds ;Point ds to
- mov dx,graphseg ; video ram.
- mov ds,dx
- xor dx,dx ;Zero relative-motion counter.
- mov cx,rangex ;Loop on the coordinate
- cmp cx,rangey ; which has the
- jl loopony ; farthest to move.
-
- ;
- ;Loop is on x.
- mov di,cx ;Value for comparison with relative-
- shr di,1 ; motion counter to di.
- inc cx ;One dot more than (x2-x1).
- xincloop:
- and [bx],al ;Turn off dot's old color,
- test ah,patmask ;Should we set bit ?
- jz xincp ;no. skip it
- xor [bx],ah ; turn on with new.
-
- ; Advance to next dot to right. We have wraparound if either
- ; shift of ah generates a carry or shift of al doesn't.
-
- xincp: ror ah,1
- jnc xnoinc1
- ror al,1
- jmp short xinc0
- xnoinc1:
- ror al,1
- jc xinc1 ;If it wrapped around,
- xinc0:
- inc bx ; advance to next byte.
- xinc1:
- add dx,rangey ;If motion in x-direction is getting
- cmp dx,di ; ahead of motion in y-direction,
- jle xinc2
- sub dx,rangex ; correct relative-motion counter.
- add bx,si ;Take a step in y-direction.
- jns xinc2 ;If overflow,
- add bx,yincalt ; correct ram address.
- xinc2: loop xincloop
- jmp short vecret ;Done.
- ;
- ;Loop on y.
- loopony:
- mov cx,rangey
- mov di,cx
- shr di,1
- inc cx
- yincloop:
- and [bx],al ;Turn off dot's old color,
- test patmask,1 ;Should we set bit ?
- jz yincp ;no. skip it
- xor [bx],ah ; turn on with new.
- yincp: rol patmask,1 ;Shift pattern mask one position
- add bx,si ;Take a step in y-direction.
- jns yinc1 ;If overflow,
- add bx,yincalt ; correct ram address.
- yinc1:
- add dx,rangex ;Update relative-motion counter.
- cmp dx,di
- jle yinc2
- sub dx,rangey
- ror ah,1 ;Increment x.
- jnc ynoinc1
- ror al,1
- jmp short yinc11
- ynoinc1:
- ror al,1
- jc yinc2 ;If it wrapped around,
- yinc11:
- inc bx ; advance to next byte.
- yinc2: loop yincloop
- ;
- vecret:
- pop ds
- add sp,tempsiz
- pop bp
- ret
- adsvec endp
-
- ;
- ;
- ;
- ; call adsmark(x,y)
- ;
- ; to reverse (draw or erase) the crosshairs centered at (x,y).
- ;
- adsmark proc far
- ; Preliminaries:
- push bp
- mov bp,sp
- push es ; always save seg regs
- mov ax,graphseg ;Base graphics ram
- mov es,ax ; on es.
-
- call hcdot ;(x,y) dot in bit cl of byte bx (and set ax)
- push ax ;Save (0,y) address.
- sub bx,ax ;(x,0) address to bx,cl.
- mov dl,10000000B ;Put a bit in
- shr dl,cl ; right column.
-
- mov cx,graphy ;Number of rows.
-
- cmp cline,0 ;If there's a
- je colloop ; status line,
- add bx,below_cline ; start vertical hair lower.
-
- ; Draw the vertical hair:
-
- colloop:
- xor es:[bx],dl ;Draw (or erase) dot(s).
- add bx,2000h ;Move up to next row.
- jns colloop1 ;If overflow,
- add bx,90-8000h ; correct address.
- colloop1:
- loop colloop
- ;
- ; Now do the horizontal hair.
-
- mov dx,graphx ;Number of dots in a row.
- call rowmask ;Get row length in bytes plus mask.
- not dx ;Invert odd-word mask.
- pop bx ;vram address of (0,y).
-
- rowloop:
- not byte ptr es:[bx] ;Invert dots wholesale.
- inc bx
- loop rowloop
-
- xor byte ptr es:[bx],dl ;Get the odd word.
- ;
- adsmret:
- pop es
- pop bp
- ret
- adsmark endp
- ;
- ;
- ;
- ; adsclr()
- ;
- ; will erase the graphics area.
-
- ; adswipe()
-
- ; will erase the whole screen.
-
- ;
- adsclr proc far
- push bp
- mov dx,graphx ;Graphics area width
- mov bp,graphy ; and height.
- xor si,si ;Start at top.
- cmp cline,0 ;If a status line,
- je clrwipe
- add si,below_cline ; start below it.
- jmp short clrwipe
-
- adswipe label far
- push bp
- mov dx,XSIZE ;Total screen width
- mov bp,YSIZE ; and height.
- xor si,si ;Start at top.
-
- ; Numbers of rows to clear in bp, number of columns in dx, starting
- ; vram address in si.
-
- clrwipe:
- push es ; Always save seg regs
- mov ax,graphseg ;Base vram on es for stos.
- mov es,ax
- call rowmask ;Convert dx to full bytes plus odd-byte mask.
- mov bx,cx ;Save byte count.
- cld ;Increment.
- xor ax,ax ;Clear color source.
-
- dsclr1:
- mov di,si ;Starting address of row.
- mov cx,bx ;Byte count.
- rep stosb ;Clear the row.
- and es:[di],dl ;Get the odd byte.
- add si,2000h ;Bump row start address.
- jns dsclr2
- add si,90-8000h
- dsclr2: dec bp ;Count it.
- jg dsclr1 ;Done?
-
- pop es
- pop bp
- ret
- adsclr endp
-
- ; Get number of complete bytes in a row of graphics area in cx
- ; and mask for the incomplete last byte in dx (0 bits for
- ; included dots), given number of dots in dx. Clobber no other
- ; registers.
-
- rowmask proc near
- mov cl,dl ;Save low bits of count.
- shr dx,1 ;Get number of full bytes.
- shr dx,1
- shr dx,1
- push dx ;Save momentarily.
- and cl,111b ;Bits in odd byte.
- mov dx,-1 ;Set up mask for
- shr dx,cl ; odd byte.
- xchg dh,dl ;That makes it backwards, of course.
- pop cx ;Word count to cx.
- ret
- rowmask endp
-
-
-
- ; Routine to draw a character at specified coordinates:
-
- ; adschar(x, y, char)
-
- ; The character box is 9 wide by 14 high, of which (x,y) is the
- ; upper left corner.
- ; The font definition doesn't include the bottom row of the
- ; character box nor the rightmost column, which are always zero.
-
- adschar proc far
- push bp
- mov bp,sp
- push es ; always save seg regs
- mov ax,graphseg ;Point es to
- mov es,ax ; video ram.
- cld
-
- mov ch,13 ;Bytes in character definition.
- mov al,args+4 ;The character.
- cmp al,7Fh ;We only print 20 thru 7F.
- jg adsc1
- sub al,20h ;Bias to start of font table.
- jge adsc2
- adsc1: xor al,al ;Print funny characters as blanks.
- adsc2: mul ch ;Find address of definition of char.
- mov si,offset dgroup:chartab
- add si,ax
-
- call hcdot ;Locate corner in video ram.
- mov dx,0111111100000000b ;Mask of 9 zero bits.
- ror dx,cl ;Position it.
- mov di,bx ;Ram offset to di.
-
- dsch1:
- lodsb ;Get byte of character definition.
- xor ah,ah ;Zero-extend it.
- ror ax,cl ;Align it.
- mov bh,es:[di+1] ;1st byte of vram it masks into.
- mov bl,es:[di] ;And the second byte.
- and bx,dx ;Clear a row of character box.
- or ax,bx ;Set new bits.
- mov es:[di+1],ah ;Put back the first byte.
- mov es:[di],al ;And the second byte.
- add di,2000h ;Move to next row of character box.
- jns dsch2
- add di,90-8000h
- dsch2: dec ch ;Loop.
- jnz dsch1
-
- and es:[di+1],dh ;Bottom row of character box.
- and es:[di],dl ;Both bytes.
-
- pop es
- pop bp
- ret
- adschar endp
-
-
-
-
- ; Routine to set the character at specified coordinates
- ; reverse video:
-
- ; dsrvid(x, y)
-
- dsrvid proc far
- push bp
- mov bp,sp
- push es ; always save seg regs
- mov ax,graphseg
- mov es,ax ;Point es to video ram.
-
- call hcdot ;Get ram address of point.
- mov si,bx ;Offset into video ram.
- mov dx,1000000011111111b ;Mask of 9 one bits.
- ror dx,cl ;Position it.
- mov cx,14 ;Rows in character box.
-
- dsrv1:
- xor es:[si],dl ;Reverse one row of character.
- xor es:[si+1],dh ;Both bytes of it.
- add si,2000h ;Proceed to next row.
- jns dsrv2
- add si,90-8000h
- dsrv2: loop dsrv1
-
- pop es
- pop bp
- ret
- dsrvid endp
-
-
- ; Scroll up the bottom n lines of the screen (the text area):
-
- ; hcscroll(n)
-
- hcscroll proc far
- push bp
- mov bp,sp
- push ds
- push es ; always save ALL seg regs
- cld
-
- mov al,args ;Lines to scroll.
- dec al
- mov ah,14 ;At 14 rows of pixels
- mul ah ; per line.
- mov bp,ax ;Save for loop counter.
- mov ax,YSIZE ;Get row number of
- sub ax,bp ; first row to scroll up.
-
- ; Compute ram address of start of that row.
- mov bx,ax ;a copy.
- shr ax,1 ;Divide by
- shr ax,1 ; 4 and multiply
- mul ninety ; by 90.
- and bx,11b ;Low 2 bits of row number.
- or ah,hibits[bx] ;Move to bits 14 and 13.
- mov si,ax ;Put it in si.
- mov di,si ;Copy to destination register.
-
- ; The following gem computes the address of the start of the 14th
- ; previous row, i.e., the top row of the previous line of text.
- sub di,(4000H+270)
- jns scr1
- sub di,90-8000h
- scr1:
-
- mov ax,graphseg ;Point both ds and
- mov ds,ax ; es to
- mov es,ax ; graphics ram.
- scr2:
- mov cx,90 ;Words in a row.
- rep movsb ;Scroll a row.
- add si,2000h-90 ;Move both pointers down a row.
- jns scr3
- add si,90-8000h
- scr3: add di,2000h-90
- jns scr4
- add di,90-8000h
- scr4: dec bp ;Do requisite number of rows.
- jnz scr2
-
- xor ax,ax ;Prepare to clear bottom line.
- mov dx,14 ;Number of rows in it.
- scr5:
- mov cx,90
- rep stosb ;Move zeroes into a row.
- add di,2000h-90 ;Advance to next row.
- jns scr6
- add di,90-8000h
- scr6: dec dx
- jnz scr5
-
- pop es
- pop ds
- pop bp
- ret
- hcscroll endp
-
- endps dsherca_
- end
-